﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ExpressionLanguage;

namespace Example2
{
    class Program
    {
        static void Main(string[] args)
        {
            // In most cases, this library is used to do configuration loading and variable assignment in much more fancier
            // way. If you want to use it as Python or PHP, I will definitely think you are joking me. Anyway, the real 
            // use case for it is just do configuration and populate those complicated external data.
            // For example you are designing a MMORPG game, it has so many numeric formula to simulate a character's ability.
            // Whatever, if you have such formula:
            // Ability.TalentPoint1 = 1.0;
            // Ability.TalentPoint2 = 1.7;
            // Ability.TalentPoint3 = 2.3;
            // Now your level designer tells you that , hey , I want the character's power is based on
            // Power = Ability.TalentPoint1 * 100 + Ability.TalentPoint2 *20 + Ability.TalentPoint3 * 10;
            // And health point is based on this:
            // Health= Ability.TalentPoint1 * 200 + Ability.TalentPoint2 *20;
            // And magic point is based on this:
            // Magic = Ability.TalentPoint2 * 40 + Ability.TalentPoint3 *80;
            // ---------------------------------------------------------------------------------------------------------------
            // Typically you can hard code this stuff into the code and make it do calculation. And you gonna suffer the pain
            // that once you change these digits, you have to modify the code and then rebuild it. 
            // But expression language is designed to do so, especially for those very complicated configuration and initialization
            // data set.

            // 1. Initialize Everything
            ExpressionInterpreter.ExecutionStack stack = new ExpressionInterpreter.ExecutionStack();
            ExpressionInterpreter.GlobalFunction function = new ExpressionInterpreter.GlobalFunction();
            CoreLibrary.LoadLibrary(function, stack);
            MathLibrary.LoadLibrary(function, stack);
            StringLibrary.LoadLibrary(function, stack);
            // 2. Write the configuration script here:
            string script = "Ability.TalentPoint1 = 1.0;" +
                "Ability.TalentPoint2 = 1.7;" +
                "Ability.TalentPoint3 = 2.3;" +
                "Power=Ability.TalentPoint1*100+Ability.TalentPoint2*20+Ability.TalentPoint3*10;" +
                "Magic=Ability.TalentPoint2 * 40 + Ability.TalentPoint3 *80;" +
                "Health= Ability.TalentPoint1 * 200 + Ability.TalentPoint2 *20;";

            // 3. Execute it
            ExpressionInterpreter.Execute(script, function, stack);
            // 4. Grab these data in our program
            double magic, power, health;

            if (!stack.LookUpAsNumber("Magic", out magic) ||
               !stack.LookUpAsNumber("Power", out power) ||
               !stack.LookUpAsNumber("Health", out health))
                return;// kidding me?

            Console.Write("Power:{0}\nMagic:{1}\nHealth:{2}\n", power, magic, health);

            return;
        }
    }
}
